/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-02-17
*/
package com.rzico.account.service;

import com.alibaba.fastjson.JSON;
import com.rzico.account.entity.Payable;
import com.rzico.account.entity.Payment;
import com.rzico.account.entity.Receivable;
import com.rzico.account.model.Attach;
import com.rzico.base.BaseMapper;
import com.rzico.base.impl.BaseServiceImpl;
import com.rzico.account.entity.Transfer;
import com.rzico.basics.entity.Enterprise;
import com.rzico.basics.entity.Member;
import com.rzico.basics.mapper.MemberMapper;
import com.rzico.basics.service.EnterpriseService;
import com.rzico.core.entity.SysEmployee;
import com.rzico.core.entity.SysMch;
import com.rzico.core.entity.SysPlugin;
import com.rzico.core.entity.SysUser;
import com.rzico.core.plugin.PaymentPlugin;
import com.rzico.core.plugin.TransferPlugin;
import com.rzico.core.service.SysMchService;
import com.rzico.core.service.SysPluginService;
import com.rzico.core.service.SysSequenceService;
import com.rzico.core.service.SysUserService;
import com.rzico.exception.CustomException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.rzico.account.mapper.TransferMapper;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * <pre>
 * 付款单业务类
 * </pre>
 *
 * @author Rzico Boot
 * @version 1.0
 */
@Service
public class TransferService extends BaseServiceImpl<Transfer, String> {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private TransferMapper transferMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private SysMchService sysMchService;

    @Autowired
    private EnterpriseService enterpriseService;

    @Autowired @Lazy
    private SysPluginService sysPluginService;

    @Autowired @Lazy
    private SysUserService sysUserService;

    @Autowired
    private SysSequenceService sysSequenceService;

    @Autowired
    private PayableService payableService;

    @Override
    public BaseMapper<Transfer, String> getMapper() {
        return transferMapper;
    }

    public Transfer findBySn(String sn){
        Map<String,Object> params = new HashMap<>();
        params.put("sn",sn);
        List<Transfer> payments = super.selectList(params);
        if (payments.size()>0) {
            return payments.get(0);
        } else {
            return null;
        }
    }

    public void handle(String sn,String tranSn) throws Exception {
        Transfer transfer = findBySn(sn);
        if (!transfer.getStatus().equals(2)) {
            transfer.setStatus(2);
            transfer.setTranSn(tranSn);
            transferMapper.updateByPrimaryKeySelective(transfer);
        }
    }

    //打款
    @Transactional(rollbackFor = Exception.class)
    public void submit(Transfer transfer,String paymentPluginId) {

        Enterprise enterprise = enterpriseService.findById(transfer.getEnterpriseId());

        SysMch sysMch = sysMchService.selectByPrimaryKey(enterprise.getMchId());
        if (sysMch.getMchType().equals(2)) {
            //特约商户,服务商代收 status
            enterprise = enterpriseService.findByMch(sysMch.getIsvId());
        }

        SysPlugin sysPlugin = sysPluginService.getEnabledPlugin(enterprise.getMchId(),paymentPluginId);

        if (sysPlugin==null) {
            return;
        }

        TransferPlugin transferPlugin = sysPluginService.getTransferPlugin(paymentPluginId);

        Member member = memberMapper.selectByPrimaryKey(transfer.getMemberId());
        SysUser sysUser = sysUserService.selectByPrimaryKey(member.getUserId());
        try {
            transfer.setStatus(1);
            transfer.setPaymentPluginId(paymentPluginId);
            transfer.setPaymentPluginName(sysPlugin.getName());
            transfer.setMemo("提现到微信零钱");
            transferMapper.updateByPrimaryKeySelective(transfer);

            Map<String,Object> result = transferPlugin.transfer(sysPlugin, transferPlugin.getUserId(sysUser), transfer.getSn(), transfer.getAmount().subtract(transfer.getFee()), transfer.getMemo());
            if (!"0000".equals(result.get("return_code").toString())) {
                throw new CustomException(result.get("error_msg").toString());
            }

        } catch (Exception e) {
            throw new CustomException(e.getMessage());
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public int insert(List<Transfer> transferList){
        int rw = 0;
        SysUser sysUser = sysUserService.getCurrent();
        Enterprise enterprise = enterpriseService.getCurrent();
        for (Transfer transfer : transferList){
            transfer.setSn(sysSequenceService.generate("order"));
            if (null == transfer.getFee()){
                transfer.setFee(BigDecimal.ZERO);
            }
            //1、保存付款单
            transfer.setPaymentDate(new Date());
            transfer.setDeleted(false);
            transfer.setType(0);
            //等待支付
            transfer.setStatus(1);
            transfer.setEnterpriseId(enterprise.getId());
            transfer.setEmployeeId(sysUser.getId());
            //2、回写应付款单的已付款金额、状态
            Payable payable = payableService.selectByPrimaryKey(transfer.getPayableId());
            transfer.setOrderId(payable.getOrderId());
            transfer.setOrderType(payable.getOrderType());
            transfer.setOrderSn(payable.getOrderSn());
            int affectCount = transferMapper.insertUseGeneratedKeys(transfer);
            if (affectCount > 0){
                rw += affectCount;
                //已付金额 = 应付款已付金额 + 本次付款金额
                BigDecimal hasPayAmount = payable.getAmountPaid().add(transfer.getAmount());
                int result = hasPayAmount.compareTo(payable.getAmount());
                if (result >= 0){
                    payable.setStatus(2);
                }else{
                    payable.setStatus(1);
                }

                payable.setAmountPaid(hasPayAmount);
                payableService.updateByPrimaryKeySelective(payable);
            }
        }
        return rw;
    }


    /**
     *  确认订单
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int confirm(Long id) {
        Transfer transfer = selectByPrimaryKey(id);
        if (null == transfer){
            throw new CustomException("付款单不存在");
        }
        if (transfer.getStatus() != 0){
            throw new CustomException("付款单无需确认");
        }

        transfer.setStatus(1);
        int affectCount = transferMapper.updateByPrimaryKeySelective(transfer);
        return affectCount;

    }


    /**
     *  取消任何状态的付款单
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int cancel(Long id) {
        Transfer transfer = selectByPrimaryKey(id);
        if (null == transfer){
            throw new CustomException("付款单不存在");
        }

        if (!"cashPayPlugin".equals(transfer.getPaymentPluginId()) && !"paperPayPlugin".equals(transfer.getPaymentPluginId())
                && !"bankPayPlugin".equals(transfer.getPaymentPluginId())) {
            throw new CustomException("线上付款订单不可取消");
        }

    /*    if (null == transfer.getPayableId()){
            throw new CustomException("没有应付款单或者线上订单不可取消");
        }*/
        if (transfer.getStatus() == 4){
            throw new CustomException("付款单已取消,请勿重复取消");
        }
        transfer.setStatus(4);
        int affectCount = transferMapper.updateByPrimaryKeySelective(transfer);
        if (affectCount > 0){

            //回写应付款单
            Payable payable = payableService.selectByPrimaryKey(transfer.getPayableId());
            BigDecimal hasPayAmount = payable.getAmountPaid().subtract(transfer.getAmount());
            payable.setAmountPaid(hasPayAmount);
            if (BigDecimal.ZERO.compareTo(payable.getAmountPaid()) == 0){
                //等待付款
                payable.setStatus(0);
            }else{
                //部分付款
                payable.setStatus(1);
            }
            payableService.updateByPrimaryKeySelective(payable);
        }
        return affectCount;
    }
}
